using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;
using LineCountEngine;

namespace LineCountGUI
{
	/// <summary>
	/// Summary description for Form1.
	/// </summary>
	public class MainForm : System.Windows.Forms.Form
	{
		private System.Windows.Forms.Panel panel;
		private System.Windows.Forms.Panel panel1;
		private System.Windows.Forms.Panel panelMain;
		private System.Windows.Forms.Splitter splitter1;
		private System.Windows.Forms.Button buttonGo;
		private System.Windows.Forms.TreeView treeView;
		private System.Windows.Forms.MainMenu mainMenu1;
		private System.Windows.Forms.MenuItem menuItem1;
		private System.Windows.Forms.MenuItem menuItem2;
		private System.Windows.Forms.MenuItem menuItem3;
		private System.Windows.Forms.MenuItem menuItem5;
		private System.Windows.Forms.MenuItem menuItemOptions;
		private System.Windows.Forms.TextBox textBoxRoot;
		private System.Drawing.PieChart.PieChartControl pieChartControl;
		private System.Windows.Forms.ProgressBar progressBar;
		private System.Windows.Forms.Label labelTitle;
		private System.Windows.Forms.Timer timer;
		private System.Windows.Forms.MenuItem menuItemStopSpinning;
		private System.Windows.Forms.MenuItem menuItem4;
		private System.Windows.Forms.MenuItem menuItemPercentages;
		private System.Windows.Forms.MenuItem menuItem8;
		private System.ComponentModel.IContainer components;

		public MainForm()
		{
			//
			// Required for Windows Form Designer support
			//
			InitializeComponent();

			//
			// TODO: Add any constructor code after InitializeComponent call
			//

			DirectoryLineCounter.DirectoryIgnoreNames = new string[] { "Bin", "obj", ".svn" };
			DirectoryLineCounter.FileSearchPatterns = new string[] { "*.cs", "*.vb" };

			pieChartControl.LeftMargin = 10;
			pieChartControl.RightMargin = 10;
			pieChartControl.TopMargin = 10;
			pieChartControl.BottomMargin = 10;
			pieChartControl.FitChart = false;
			pieChartControl.EdgeColorType = System.Drawing.PieChart.EdgeColorType.DarkerThanSurface;
			pieChartControl.InitialAngle = -30;
			pieChartControl.SliceRelativeHeight = 0.20f;
			pieChartControl.SliceSelected += new System.Drawing.PieChart.SliceSelectedHandler(pieChartControl_SliceSelected);

			timer.Start();

			menuItemPercentages.Checked = percentages;
		}

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if (components != null) 
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.components = new System.ComponentModel.Container();
			System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(MainForm));
			this.panel = new System.Windows.Forms.Panel();
			this.textBoxRoot = new System.Windows.Forms.TextBox();
			this.buttonGo = new System.Windows.Forms.Button();
			this.progressBar = new System.Windows.Forms.ProgressBar();
			this.panel1 = new System.Windows.Forms.Panel();
			this.treeView = new System.Windows.Forms.TreeView();
			this.panelMain = new System.Windows.Forms.Panel();
			this.pieChartControl = new System.Drawing.PieChart.PieChartControl();
			this.labelTitle = new System.Windows.Forms.Label();
			this.splitter1 = new System.Windows.Forms.Splitter();
			this.mainMenu1 = new System.Windows.Forms.MainMenu();
			this.menuItem1 = new System.Windows.Forms.MenuItem();
			this.menuItem2 = new System.Windows.Forms.MenuItem();
			this.menuItem3 = new System.Windows.Forms.MenuItem();
			this.menuItemStopSpinning = new System.Windows.Forms.MenuItem();
			this.menuItemPercentages = new System.Windows.Forms.MenuItem();
			this.menuItem4 = new System.Windows.Forms.MenuItem();
			this.menuItemOptions = new System.Windows.Forms.MenuItem();
			this.menuItem5 = new System.Windows.Forms.MenuItem();
			this.timer = new System.Windows.Forms.Timer(this.components);
			this.menuItem8 = new System.Windows.Forms.MenuItem();
			this.panel.SuspendLayout();
			this.panel1.SuspendLayout();
			this.panelMain.SuspendLayout();
			this.SuspendLayout();
			// 
			// panel
			// 
			this.panel.Controls.Add(this.textBoxRoot);
			this.panel.Controls.Add(this.buttonGo);
			this.panel.Controls.Add(this.progressBar);
			this.panel.Dock = System.Windows.Forms.DockStyle.Top;
			this.panel.Location = new System.Drawing.Point(0, 0);
			this.panel.Name = "panel";
			this.panel.Size = new System.Drawing.Size(592, 28);
			this.panel.TabIndex = 0;
			// 
			// textBoxRoot
			// 
			this.textBoxRoot.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
				| System.Windows.Forms.AnchorStyles.Right)));
			this.textBoxRoot.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
			this.textBoxRoot.Location = new System.Drawing.Point(196, 4);
			this.textBoxRoot.Name = "textBoxRoot";
			this.textBoxRoot.Size = new System.Drawing.Size(388, 20);
			this.textBoxRoot.TabIndex = 2;
			this.textBoxRoot.Text = "c:\\src\\tinkering";
			this.textBoxRoot.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.textBoxRoot_KeyPress);
			// 
			// buttonGo
			// 
			this.buttonGo.FlatStyle = System.Windows.Forms.FlatStyle.System;
			this.buttonGo.Location = new System.Drawing.Point(8, 4);
			this.buttonGo.Name = "buttonGo";
			this.buttonGo.Size = new System.Drawing.Size(32, 20);
			this.buttonGo.TabIndex = 1;
			this.buttonGo.Text = "GO";
			this.buttonGo.Click += new System.EventHandler(this.buttonGo_Click);
			// 
			// progressBar
			// 
			this.progressBar.Location = new System.Drawing.Point(48, 6);
			this.progressBar.Name = "progressBar";
			this.progressBar.Size = new System.Drawing.Size(124, 16);
			this.progressBar.TabIndex = 1;
			// 
			// panel1
			// 
			this.panel1.Controls.Add(this.treeView);
			this.panel1.Dock = System.Windows.Forms.DockStyle.Left;
			this.panel1.Location = new System.Drawing.Point(0, 28);
			this.panel1.Name = "panel1";
			this.panel1.Size = new System.Drawing.Size(188, 269);
			this.panel1.TabIndex = 1;
			// 
			// treeView
			// 
			this.treeView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
				| System.Windows.Forms.AnchorStyles.Left) 
				| System.Windows.Forms.AnchorStyles.Right)));
			this.treeView.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
			this.treeView.ImageIndex = -1;
			this.treeView.Location = new System.Drawing.Point(8, 5);
			this.treeView.Name = "treeView";
			this.treeView.SelectedImageIndex = -1;
			this.treeView.Size = new System.Drawing.Size(176, 258);
			this.treeView.TabIndex = 0;
			this.treeView.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeView_AfterSelect);
			// 
			// panelMain
			// 
			this.panelMain.BackColor = System.Drawing.Color.FromArgb(((System.Byte)(255)), ((System.Byte)(255)), ((System.Byte)(192)));
			this.panelMain.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
			this.panelMain.Controls.Add(this.pieChartControl);
			this.panelMain.Controls.Add(this.labelTitle);
			this.panelMain.Dock = System.Windows.Forms.DockStyle.Fill;
			this.panelMain.Location = new System.Drawing.Point(191, 28);
			this.panelMain.Name = "panelMain";
			this.panelMain.Size = new System.Drawing.Size(401, 269);
			this.panelMain.TabIndex = 2;
			// 
			// pieChartControl
			// 
			this.pieChartControl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
				| System.Windows.Forms.AnchorStyles.Left) 
				| System.Windows.Forms.AnchorStyles.Right)));
			this.pieChartControl.InitialAngle = 0F;
			this.pieChartControl.Location = new System.Drawing.Point(42, 40);
			this.pieChartControl.Name = "pieChartControl";
			this.pieChartControl.Size = new System.Drawing.Size(312, 204);
			this.pieChartControl.TabIndex = 0;
			this.pieChartControl.ToolTips = null;
			this.pieChartControl.Resize += new System.EventHandler(this.pieChartControl_Resize);
			this.pieChartControl.MouseEnter += new System.EventHandler(this.pieChartControl_MouseEnter);
			this.pieChartControl.MouseLeave += new System.EventHandler(this.pieChartControl_MouseLeave);
			// 
			// labelTitle
			// 
			this.labelTitle.Dock = System.Windows.Forms.DockStyle.Top;
			this.labelTitle.Font = new System.Drawing.Font("Microsoft Sans Serif", 11F, ((System.Drawing.FontStyle)((System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Underline))), System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.labelTitle.Location = new System.Drawing.Point(0, 0);
			this.labelTitle.Name = "labelTitle";
			this.labelTitle.Size = new System.Drawing.Size(397, 23);
			this.labelTitle.TabIndex = 0;
			this.labelTitle.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
			// 
			// splitter1
			// 
			this.splitter1.Location = new System.Drawing.Point(188, 28);
			this.splitter1.Name = "splitter1";
			this.splitter1.Size = new System.Drawing.Size(3, 269);
			this.splitter1.TabIndex = 3;
			this.splitter1.TabStop = false;
			// 
			// mainMenu1
			// 
			this.mainMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
																											 this.menuItem1,
																											 this.menuItem3,
																											 this.menuItem5});
			// 
			// menuItem1
			// 
			this.menuItem1.Index = 0;
			this.menuItem1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
																											 this.menuItem2});
			this.menuItem1.Text = "File";
			// 
			// menuItem2
			// 
			this.menuItem2.Index = 0;
			this.menuItem2.Text = "Exit";
			this.menuItem2.Click += new System.EventHandler(this.menuItem2_Click);
			// 
			// menuItem3
			// 
			this.menuItem3.Index = 1;
			this.menuItem3.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
																											 this.menuItemStopSpinning,
																											 this.menuItemPercentages,
																											 this.menuItem4,
																											 this.menuItemOptions});
			this.menuItem3.Text = "View";
			// 
			// menuItemStopSpinning
			// 
			this.menuItemStopSpinning.Index = 0;
			this.menuItemStopSpinning.Text = "Stop Spinning !";
			this.menuItemStopSpinning.Click += new System.EventHandler(this.menuItemStopSpinning_Click);
			// 
			// menuItemPercentages
			// 
			this.menuItemPercentages.Index = 1;
			this.menuItemPercentages.Text = "Percentages";
			this.menuItemPercentages.Click += new System.EventHandler(this.menuItemPercentages_Click);
			// 
			// menuItem4
			// 
			this.menuItem4.Index = 2;
			this.menuItem4.Text = "-";
			// 
			// menuItemOptions
			// 
			this.menuItemOptions.Index = 3;
			this.menuItemOptions.Text = "Options...";
			this.menuItemOptions.Click += new System.EventHandler(this.menuItemOptions_Click);
			// 
			// menuItem5
			// 
			this.menuItem5.Index = 2;
			this.menuItem5.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
																											 this.menuItem8});
			this.menuItem5.Text = "Help";
			// 
			// timer
			// 
			this.timer.Tick += new System.EventHandler(this.timer_Tick);
			// 
			// menuItem8
			// 
			this.menuItem8.Index = 0;
			this.menuItem8.Text = "By Shane Seaton";
			// 
			// MainForm
			// 
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
			this.ClientSize = new System.Drawing.Size(592, 297);
			this.Controls.Add(this.panelMain);
			this.Controls.Add(this.splitter1);
			this.Controls.Add(this.panel1);
			this.Controls.Add(this.panel);
			this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
			this.Menu = this.mainMenu1;
			this.Name = "MainForm";
			this.Text = "Line Counter";
			this.Resize += new System.EventHandler(this.MainForm_Resize);
			this.panel.ResumeLayout(false);
			this.panel1.ResumeLayout(false);
			this.panelMain.ResumeLayout(false);
			this.ResumeLayout(false);

		}
		#endregion

		protected bool percentages = true;

		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		static void Main() 
		{
			Application.EnableVisualStyles();
			Application.DoEvents();
			Application.Run(new MainForm());
		}

		private void buttonGo_Click(object sender, System.EventArgs e)
		{
			Reset();
			if( Directory.Exists( textBoxRoot.Text ) )
			{
				DirectoryLineCounter counter = new DirectoryLineCounter( new DirectoryInfo( textBoxRoot.Text ) );
				counter.FilesCompleted += new FilesCompletedHandler(counter_FilesCompleted);
				progressBar.Maximum = counter.filesToCount();
				counter.countLines();
				BuildTree( counter );
			}
			else
				MessageBox.Show( "The directory \"" + textBoxRoot.Text+ "\" does not exist." );
		}

		private void menuItemOptions_Click(object sender, System.EventArgs e)
		{
			OptionsForm form = new OptionsForm();
			
			form.IgnoreDirectories = DirectoryLineCounter.DirectoryIgnoreNames;
			form.FilePatterns = DirectoryLineCounter.FileSearchPatterns;

			form.ShowDialog();

			DirectoryLineCounter.DirectoryIgnoreNames = form.IgnoreDirectories;
			DirectoryLineCounter.FileSearchPatterns = form.FilePatterns;
		}

		protected void Reset()
		{
			treeView.Nodes.Clear();
			progressBar.Value = 0;
		}

		protected void BuildTree( DirectoryLineCounter root )
		{
			TreeNode rootNode = new TreeNode( root.Directory.Name + " (" + root.TotalLines.ToString() + ")" );
			rootNode.Tag = root;
			AddChildNodes( rootNode, root );
			treeView.Nodes.Add( rootNode );
			rootNode.Expand();
			treeView.SelectedNode = rootNode;
			treeView.Select();
			UpdateForm();
		}

		protected void AddChildNodes( TreeNode rootNode, DirectoryLineCounter root )
		{
			foreach( DirectoryLineCounter dlc in root.SubDirectoryCounters )
			{
				string num = dlc.TotalLines.ToString();
//				if( percentages )
//					num = (root.TotalLines > 0 ?((float)(dlc.TotalLines / (float)root.TotalLines * 100f)).ToString("f1") + "%": "0%" );

				TreeNode node = new TreeNode( dlc.Directory.Name + " (" + num + ")" );
				node.Tag = dlc;
				AddChildNodes( node, dlc );
				rootNode.Nodes.Add( node );
			}
			
			if( root.SubDirectoryCounters.Length > 0 )
			{
				string num = root.DirectoryLines.ToString();
//				if( percentages )
//					num = (root.TotalLines > 0 ?((float)(root.DirectoryLines / (float)root.TotalLines * 100f)).ToString("f1") + "%": "0%" );
				rootNode.Nodes.Add( "Files (" + num + ")" );
			}		
		}

		protected void UpdateForm( )
		{
			if( treeView.SelectedNode != null )
			{
				labelTitle.Text = treeView.SelectedNode.Text;

				if( treeView.SelectedNode.Nodes.Count == 0 )
				{
					pieChartControl.Values = new decimal[]{ 100 };
					pieChartControl.Colors = new Color[]{ Color.Red };
					pieChartControl.ToolTips = new string[] {treeView.SelectedNode.Text};
					pieChartControl.Tags = new object[] { treeView.SelectedNode };
				}
				else
				{
					decimal[] values = new decimal[treeView.SelectedNode.Nodes.Count];
					Color[] colors = new Color[values.Length];
					string[] hints = new string[values.Length];
					object[] tags = new object[ values.Length ];

					int i = 0;
					foreach( TreeNode childNode in treeView.SelectedNode.Nodes )
					{
						DirectoryLineCounter dlc = childNode.Tag as DirectoryLineCounter;
						if( dlc != null )
							values[i] = dlc.TotalLines;
						else
							values[i] = ((DirectoryLineCounter)treeView.SelectedNode.Tag).DirectoryLines;

						if( percentages )
						{
							if( ((DirectoryLineCounter)treeView.SelectedNode.Tag).TotalLines == 0 )
								values[i] = 0;
							else
								values[i] = (decimal)((float)values[i] / (float)((DirectoryLineCounter)treeView.SelectedNode.Tag).TotalLines * 100.0f);
							string extension = " (" + values[i].ToString( "f1" ) + "%)";
							if( dlc != null )
								hints[i] = dlc.Directory.Name + extension;
							else
								hints[i] = "Files" + extension;
						}
						else
							hints[i] = childNode.Text;

						colors[i] = decentColors[ i % decentColors.Length ];
						tags[i] = childNode;
						i++;
					}

					pieChartControl.Colors = colors;
					pieChartControl.ToolTips = hints;
					pieChartControl.Tags = tags;
					decimal total = 0;
					foreach( decimal v in values )
					{
						total += v;
					}
					if( total > 0 )
						pieChartControl.Values = values;
					else
						pieChartControl.Values = null;
				}
			}
			else
			{
				pieChartControl.Values = null;
				labelTitle.Text = "";
			}
		}

		protected Color[] decentColors = new Color[]{ Color.Red, 
																	  Color.Yellow, 
																	  Color.DodgerBlue, 
																	  Color.LightGreen, 
																	  Color.Coral, 
																	  Color.Goldenrod, 
																	  Color.YellowGreen, 
																	  Color.MediumPurple,
																	  Color.LightGray, 
																	  Color.Brown, 
																	  Color.Pink, 
																	  Color.DarkBlue, 
																	  Color.Purple };

		private void treeView_AfterSelect(object sender, System.Windows.Forms.TreeViewEventArgs e)
		{
			e.Node.Expand();
			UpdateForm();
		}

		private void pieChartControl_Resize(object sender, System.EventArgs e)
		{
		}

		private void MainForm_Resize(object sender, System.EventArgs e)
		{
			pieChartControl.LeftMargin = 10;
			pieChartControl.RightMargin = 10;
			pieChartControl.TopMargin = 10;
			pieChartControl.BottomMargin = 10;

			if( pieChartControl.Height*2 > pieChartControl.Width )
			{
				int chartWidth = pieChartControl.Width - 20;
				pieChartControl.TopMargin = ( pieChartControl.Height - chartWidth/2 ) / 2;
				pieChartControl.BottomMargin = ( pieChartControl.Height - chartWidth/2 ) / 2; 
			}
			else
			{
				int chartHeight = pieChartControl.Height - 20;
				pieChartControl.LeftMargin = (pieChartControl.Width - chartHeight*2) / 2;
				pieChartControl.RightMargin = (pieChartControl.Width - chartHeight*2) / 2;
			}
		}

		private void pieChartControl_SliceSelected(object sender, System.Drawing.PieChart.SliceSelectedArgs e)
		{
			if( e.tag != null )
			{				
				TreeNode node = e.tag as TreeNode;
				treeView.SelectedNode = node;
			}
		}

		private void counter_FilesCompleted(object sender, int filesCompleted)
		{
			progressBar.Value += filesCompleted;
			Application.DoEvents();
		}

		private void textBoxRoot_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
		{
			if( e.KeyChar == (char)13 ) //enter key
			{
				buttonGo_Click( this, EventArgs.Empty );
			}
		}

		private void timer_Tick(object sender, System.EventArgs e)
		{
			if( !menuItemStopSpinning.Checked )
				pieChartControl.InitialAngle = ( pieChartControl.InitialAngle + 2f ) % 360f;
		}

		private void pieChartControl_MouseEnter(object sender, System.EventArgs e)
		{
			timer.Stop();
		}

		private void pieChartControl_MouseLeave(object sender, System.EventArgs e)
		{
			timer.Start();
		}

		private void menuItem2_Click(object sender, System.EventArgs e)
		{
			Close();
		}

		private void menuItemStopSpinning_Click(object sender, System.EventArgs e)
		{
			menuItemStopSpinning.Checked = !menuItemStopSpinning.Checked;
			if( menuItemStopSpinning.Checked )
				timer.Stop();
			else
				timer.Start();
		}

		private void menuItemPercentages_Click(object sender, System.EventArgs e)
		{
			percentages = !percentages;
			menuItemPercentages.Checked = percentages;
		}
	}
}

